
# 小游戏 勇者斗恶龙

# 玩家
# 怪物
# 公主


# N*N地图


# 游戏角色
import random                                 # 导入一个随机数库

class GameRole():                # 创建一个游戏角色的类

    # 初始化 角色名与角色出生位置
    def __init__(self,name,x,y):
        self.name = name
        self.x = x
        self.y = y

    # 角色移动
    def move(self,d=''):
        ds = ['w','a','s','d']            # 这里用一个列表 来保存怪物和公主随机移动时对应的字母
        if d == '':
            d = ds[random.randint(0,3)]
        if d == 'w' and self.y > 1 :
            # print(self.name+'向上走')
            self.y -= 1
        elif d == 'd' and self.x < 10 :
            # print(self.name+'向右走')
            self.x += 1
        elif d == 's' and self.y < 10 :
            # print(self.name+'向下走')
            self.y += 1
        elif d == 'a' and self.x > 1 :
            # print(self.name+'向左走')
            self.x -= 1

    def __str__(self):
        return f"{self.name} 坐标{self.x}，{self.y}"

class Hero(GameRole):      # 定义一个英雄的类
    def __init__(self,x,y):                     # 这里之所以有黄色警告，是子类hero中的初始变量值将会覆盖父类的初始变量
        self.name = '英雄'
        self.x = x
        self.y = y

    def move(self):                             # 这里之所以有黄色警告，是子类中的移动（move）行为将会覆盖父类中的移动（move）行为
        d = input('请输入移动方向（w向上d向右s向下a向左）：')
        super().move(d)                                 # 这里是子类Hero 调用父类 函数的一种表现方式

class Monster(GameRole):
    def __init__(self):                        # 这里之所以有黄色警告，是子类monster中的初始变量值将会覆盖父类的初始变量
        self.name = '怪物'
        self.x = random.randint(1,10)
        self.y = random.randint(1,10)

class Princess(GameRole):
    def __init__(self,x,y):                    # 这里之所以有黄色警告，是子类princess中的初始变量值将会覆盖父类的初始变量
        self.name = '公主'
        self.x = x
        self.y = y


class Game():                                 # 这里定义了一个游戏类
    def __init__(self):                       # 注意这里的初始值的定义 使得游戏类 与 英雄类、怪物类、公主类、形成了组合关系
        self.hero = Hero(1,1)                 # 并且由于英雄类、怪物类、公主类属于角色类的子类，那么这里的变量hero、monster。princess也就具有了角色类的行为
        self.monster = Monster()
        self.princess = Princess(10,10)

    def printMap(self):                       # 这里通过两层循环实现了打印地图功能的封装
        for i in range(1,11):
            for j in range(1,11):
                if self.hero.x == j and self.hero.y == i :
                    print('🤴',end='')
                elif self.monster.x == j and self.monster.y == i :
                    print('💀',end='')
                elif self.princess.x == j and self.princess.y == i :
                    print('👸',end='')
                else:
                    print("⬜",end='')
            print('')
        pass

    def roleMove(self):                    # 这里就是游戏类中变量 通过 与 玩家类、怪物类、公主类的组合关系 实现了调用游戏角色类的行为
        self.hero.move()
        self.monster.move()
        self.princess.move()


    def checkwin(self):                   # 这里是封装了一个判断输赢的功能  具体是通过判断玩家与怪兽和公主的位置关系来给出一个返回值 再根据返回值来判断输赢
        if self.hero.x == self.princess.x and self.hero.y == self.princess.y:
            return 1
        elif self.hero.x == self.monster.x and self.hero.y == self.monster.y:
            return -1
        return 0

    # 游戏主流程
    def paly(self):
        self.printMap()
        while True:                             # 通过一个while的死循环 来实现游戏不断玩下去的效果
            self.roleMove()                     # 游戏主要功能之一 角色移动
            self.printMap()                     # 游戏主要功能之二 打印地图
            self.checkwin()                     # 游戏主要功能之三 判断输赢
            result = self.checkwin()
            if result == 1:
                print('玩家追上了公主，You win！')
                break
            elif result == -1:
                print('玩家被怪物抓到，You lose！')
                break
        print('游戏结束')

game = Game()
game.paly()


